#include "src/include/mainwindow.h"
#include "./ui_mainwindow.h"
#include "include/core.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QButtonGroup>
#include <QOpenGLBuffer>
#include <iostream>

using namespace std;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->pushButton_2, SIGNAL(clicked()), this, SLOT(loadFromFile()));
    connect(ui->pushButton_3, SIGNAL(clicked()), this, SLOT(saveToFile()));
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(calChain()));

    QButtonGroup radioGroup_1(this);
    radioGroup_1.addButton(ui->radioButton_n);
    radioGroup_1.addButton(ui->radioButton_w);
    radioGroup_1.addButton(ui->radioButton_c);

    QButtonGroup radioGroup_2(this);
    radioGroup_2.addButton(ui->radioButton_h);
    radioGroup_2.addButton(ui->radioButton_t);
    radioGroup_2.addButton(ui->radioButton_j);
    radioGroup_2.addButton(ui->radioButton_r);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::loadFromFile() {
    QString filename = QFileDialog::getOpenFileName(this,nullptr, nullptr, "Text files (*.txt);; *.*");
    if (filename.isEmpty()) {
        QMessageBox::warning(this, "Warning!", "Failed to open the file.");
    } else {
        QFile file(filename);
        if (!file.open(QFile::ReadOnly | QFile::Text)) {
            QMessageBox::warning(this, "Warning!", "Failed to open the file.");
        }
        QTextStream in(&file);
        QString inStr = in.readAll();
        ui->textEdit->setText(inStr);
    }
}

void MainWindow::calChain() {
    char **words = new char * [2000];
    int words_len = getWords(ui->textEdit->toPlainText(), words);
    cout << words_len << endl;
    for (int i = 0; i < words_len; i++) {
        cout << words[i] << endl;
    }
    int n = ui->radioButton_n->isChecked();
    int w = ui->radioButton_w->isChecked();
    int c = ui->radioButton_c->isChecked();
    int h = ui->radioButton_h->isChecked();
    int t = ui->radioButton_t->isChecked();
    int j = ui->radioButton_j->isChecked();
    int r = ui->radioButton_r->isChecked();
    char h_char = (h > 0) ? ui->comboBox_h->currentIndex() + 'a' : 0;
    char t_char = (t > 0) ? ui->comboBox_t->currentIndex() + 'a' : 0;
    char j_char = (j > 0) ? ui->comboBox_j->currentIndex() + 'a' : 0;
    if (n && (h + t + j + r)) {
        QMessageBox::warning(this, "Warning!", "Parameter -n can only be use alone.");
    }
    HMODULE core = LoadLibraryA("core.dll");
    int ret;
    char **result = new char * [1000];
    try {
        if (n) {
            ret = gen_chains_all(words, words_len, result);
        } else if (w) {
            ret = gen_chain_word(words, words_len, result, h_char, t_char, j_char, r);
        } else if (c) {
            ret = gen_chain_char(words, words_len, result, h_char, t_char, j_char, r);
        } else {
            QMessageBox::warning(this, "Warning!", "Please select a function parameter.");
        }
    } catch (exception &e) {
        QMessageBox::warning(this, "Warning", e.what());
        return;
    }
    
    QString str;
    if (n) {
        str = QString::number(ret);
        str.append("\n");
    }
    for (int i = 0; i < ret; i++) {
        str.append(result[i]).append("\n");
    }
    if (ret < 2 && !n) {
        str = "There are no qualified word chains.";
    }
    ui->textEdit_2->setText(str);
    for (int i = 0; i < words_len; i++) {
        free(words[i]);
    }
    FreeLibrary(core);
}

void MainWindow::saveToFile() {
    QString filename = QFileDialog::getSaveFileName(this, nullptr, "solution.txt", "Text files (*.txt)");
    if (filename.isEmpty()) {
        QMessageBox::warning(this, "Warning!", "Failed to save the file.");
    }
    QFile qFile(filename);
    if (!qFile.open(QIODevice::WriteOnly)) {
        QMessageBox::warning(this, "Warning!", "Failed to save the file.");
    }
    QTextStream stream(&qFile);
    stream << ui->textEdit_2->toPlainText();
    qFile.close();
}

int MainWindow::getWords(const QString& qString, char* words[]) {
    int len = 0;
    string content = qString.toStdString();
    int head, tail = 0;
    while (true) {
        for(head = tail; head < content.length(); head++) {
            if (isalpha(content[head])) {
                break;
            }
        }
        for (tail = head; tail < content.length(); tail++) {
            if (!isalpha(content[tail])) {
                break;
            }
        }
        if (head == content.length()) {
            break;
        }
        words[len] = new char[tail - head + 10];
        strcpy(words[len], content.substr(head, tail - head).data());
        len++;
    }
    return len;
}

